using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace XNATetris
{
    public class OnePlayerMode : Microsoft.Xna.Framework.DrawableGameComponent
    {
        public OnePlayerMode(Game game)
            : base(game)
        {
        }
        
        public override void Initialize()
        {
            TetrisLogic.destroy_game();

            TetrisLogic.update_variable();
            TetrisLogic.init_block_matrix();

            base.Initialize();
        }

        SpriteBatch spriteBatch;
        SpriteFont spriteFont;
        SoundEffect soundEffect;
        SoundEffectInstance sei;
        Texture2D IPiece;
        Texture2D JPiece;
        Texture2D LPiece;
        Texture2D OPiece;
        Texture2D SPiece;
        Texture2D TPiece;
        Texture2D ZPiece;
        Texture2D PlayGround;

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            spriteFont = Game.Content.Load<SpriteFont>("font");

            soundEffect = Game.Content.Load<SoundEffect>("tetrisSong");

            sei = soundEffect.CreateInstance();
            sei.IsLooped = true;
            sei.Play();

            IPiece = Game.Content.Load<Texture2D>("IPiece2");
            JPiece = Game.Content.Load<Texture2D>("JPiece2");
            LPiece = Game.Content.Load<Texture2D>("LPiece2");
            OPiece = Game.Content.Load<Texture2D>("OPiece2");
            SPiece = Game.Content.Load<Texture2D>("SPiece2");
            TPiece = Game.Content.Load<Texture2D>("TPiece2");
            ZPiece = Game.Content.Load<Texture2D>("ZPiece2");
            PlayGround = Game.Content.Load<Texture2D>("PlayGround");
#if WINDOWS
            oldState = Keyboard.GetState();
#endif

#if XBOX360
            oldState = GamePad.GetState(PlayerIndex.One);
#endif
            TetrisLogic.init_game();

            base.LoadContent();
        }

#if WINDOWS
        KeyboardState oldState;
#endif

#if XBOX360
        GamePadState oldState;
#endif
        public override void Update(GameTime gameTime)
        {
            bool gameOver = TetrisLogic.update_script();
#if WINDOWS
            if (Keyboard.GetState().IsKeyDown(Keys.Space))
            {
                Game.Components.Add(new Menu(Game));

                Enabled = false;
            }
#endif

#if XBOX360
            if (GamePad.GetState(PlayerIndex.One).IsButtonDown(Buttons.Start))
            {
                Game.Components.Add(new Menu(Game));

                Enabled = false;
            }
#endif
            if (gameOver)
            {
                sei.Stop();

                TetrisLogic.destroy_game();

                while (Game.Components.Count > 0)
                {
                    Game.Components.RemoveAt(0);
                }
                Game.Services.RemoveService(typeof(IInputService));

                Game.Components.Add(new Menu(Game));
            }
#if WINDOWS
            oldState = Keyboard.GetState();
#endif

#if XBOX360
            oldState = GamePad.GetState(PlayerIndex.One);
#endif

            base.Update(gameTime);
        }

        int pieceWH = 32;
        public override void Draw(GameTime gameTime)
        {
            spriteBatch.Begin();

            spriteBatch.Draw(PlayGround, new Rectangle(0, 0, 800, 600), Color.White);

            spriteBatch.DrawString(spriteFont, "Score: " + TetrisLogic.tetris_state.GetScore(), new Vector2(557.0f, 67.0f), Color.White);
            spriteBatch.DrawString(spriteFont, "Level: " + TetrisLogic.tetris_state.GetLevel(), new Vector2(557.0f, 131.0f), Color.White);

            Texture2D texture = getTexture(TetrisLogic.tetris_state.GetNextName());

            spriteBatch.Draw(texture, new Rectangle(TetrisLogic.tetris_state.GetNextX(0) + 275, TetrisLogic.tetris_state.GetNextY(0) + 300, pieceWH, pieceWH), new Rectangle(0, 0, pieceWH, pieceWH), Color.White);
            spriteBatch.Draw(texture, new Rectangle(TetrisLogic.tetris_state.GetNextX(1) + 275, TetrisLogic.tetris_state.GetNextY(1) + 300, pieceWH, pieceWH), new Rectangle(0, 0, pieceWH, pieceWH), Color.White);
            spriteBatch.Draw(texture, new Rectangle(TetrisLogic.tetris_state.GetNextX(2) + 275, TetrisLogic.tetris_state.GetNextY(2) + 300, pieceWH, pieceWH), new Rectangle(0, 0, pieceWH, pieceWH), Color.White);
            spriteBatch.Draw(texture, new Rectangle(TetrisLogic.tetris_state.GetNextX(3) + 275, TetrisLogic.tetris_state.GetNextY(3) + 300, pieceWH, pieceWH), new Rectangle(0, 0, pieceWH, pieceWH), Color.White);

            texture = getTexture(TetrisLogic.tetris_state.GetName());

            spriteBatch.Draw(texture, new Rectangle(TetrisLogic.tetris_state.GetX(0), TetrisLogic.tetris_state.GetY(0), pieceWH, pieceWH), new Rectangle(0, 0, pieceWH, pieceWH), Color.White);
            spriteBatch.Draw(texture, new Rectangle(TetrisLogic.tetris_state.GetX(1), TetrisLogic.tetris_state.GetY(1), pieceWH, pieceWH), new Rectangle(0, 0, pieceWH, pieceWH), Color.White);
            spriteBatch.Draw(texture, new Rectangle(TetrisLogic.tetris_state.GetX(2), TetrisLogic.tetris_state.GetY(2), pieceWH, pieceWH), new Rectangle(0, 0, pieceWH, pieceWH), Color.White);
            spriteBatch.Draw(texture, new Rectangle(TetrisLogic.tetris_state.GetX(3), TetrisLogic.tetris_state.GetY(3), pieceWH, pieceWH), new Rectangle(0, 0, pieceWH, pieceWH), Color.White);

            for (int i = 0; i < TetrisLogic.tetris_state.GetPlacedBricksLength(); ++i)
            {
                texture = getTexture(TetrisLogic.tetris_state.GetPlacedBrickName(i));
                spriteBatch.Draw(texture, new Rectangle(TetrisLogic.tetris_state.GetPlacedBrickX(i), TetrisLogic.tetris_state.GetPlacedBrickY(i), pieceWH, pieceWH), new Rectangle(0, 0, pieceWH, pieceWH), Color.White);
            }

                spriteBatch.End();
           
            base.Draw(gameTime);
        }

        protected override void OnEnabledChanged(object sender, EventArgs args)
        {
            if (sei.State == SoundState.Stopped)
                sei.Play();
            else
                sei.Stop();
            
            base.OnEnabledChanged(sender, args);
        }

        private Texture2D getTexture(TetrisState.BlockName name)
        {
            if (name == TetrisState.BlockName.IPiece)
                return IPiece;
            else if (name == TetrisState.BlockName.JPiece)
                return JPiece;
            else if (name == TetrisState.BlockName.LPiece)
                return LPiece;
            else if (name == TetrisState.BlockName.OPiece)
                return OPiece;
            else if (name == TetrisState.BlockName.SPiece)
                return SPiece;
            else if (name == TetrisState.BlockName.TPiece)
                return TPiece;
            else if (name == TetrisState.BlockName.ZPiece)
                return ZPiece;
            else
                return null;
        }
    }
}
